import React from 'react';
import { Input, Icon, Modal, Tooltip, message } from 'antd';
import { Map, Marker } from 'react-amap';
import Address from '@/components/AMap/Address';

const MapIcon = <Icon type="environment" />;

const style = {
  padding: 0,
  height: 500,
  width: 700,
};

const markerStyle = {
  width: 19,
  height: 33,
};

const MarkerImage = () => (
  <img
    src="http://webapi.amap.com/theme/v1.3/markers/b/mark_bs.png"
    style={markerStyle}
    alt="marker"
  />
);

const MarkerIcon = props => <Icon component={MarkerImage} {...props} />;

export default class AddressInput extends React.Component {
  static defaultProps = {
    mapProps: {},
    bodyStyle: style,
    onClick: () => {},
  };

  static getDerivedStateFromProps(nextProps, preStates) {
    if ('value' in nextProps && nextProps.value) {
      const { value } = nextProps;
      let { result } = preStates;
      if (!value.position) {
        result = result || {
          position: null,
          address: value,
        };
      } else {
        result =
          value.value !== preStates.value || preStates.result === undefined
            ? {
                address: value.value,
                position: value.position,
              }
            : preStates.result;
      }

      return {
        ...(nextProps.value || {}),
        result,
      };
    }
    return null;
  }

  constructor(props) {
    super(props);
    const propsValue = props.value;

    const value = propsValue ? propsValue.value : '';
    this.state = {
      visible: false,
      value,
      result: undefined,
    };

    this.amapEvents = {
      created: ins => {
        this.instance = ins;
      },
      click: e => {
        const { lnglat } = e;
        this.instance.plugin('AMap.Geocoder', () => {
          const geocoder = new window.AMap.Geocoder();
          geocoder.setCity(props.mapProps.city || '027');
          geocoder.getAddress(lnglat, (status, result) => {
            if (status === 'complete' && result.regeocode) {
              this.setState({
                result: {
                  address: result.regeocode.formattedAddress,
                  adcode: result.regeocode.addressComponent.adcode,
                  position: { ...lnglat },
                },
              });
            } else {
              message.warn('没有找到该点的地址信息！');
            }
          });
        });
      },
    };
  }

  handleClick = e => {
    const { onClick } = this.props;
    const promise = onClick(e);
    if (promise === false) return null;
    if (promise instanceof Promise) {
      return promise.then(() => {
        this.setState({
          visible: true,
        });
      });
    }
    this.setState({
      visible: true,
    });
    return null;
  };

  handleOk = () => {
    const { result } = this.state;
    if (result) {
      const { position, adcode, address } = result;
      this.setState({
        visible: false,
        value: address,
      });
      this.triggerChange({
        position,
        adcode,
        value: address,
      });
    } else {
      this.setState({
        visible: false,
      });
      this.triggerChange(undefined);
    }
  };

  handleCancel = e => {
    this.setState({
      visible: false,
      result: undefined,
    });
  };

  handleSearch = res => {
    if (res) {
      this.setState({
        result: {
          address: res[0].formattedAddress,
          adcode: res[0].adcode,
          position: res[0].location,
        },
      });
    } else {
      message.warn('未搜索到改地址信息，请输入更详细的地址');
    }
  };

  handleChange = e => {
    this.setState({
      value: e.target.value,
      result: undefined,
    });
    this.triggerChange(undefined);
  };

  triggerChange = changedValue => {
    // Should provide an event to pass value to Form.
    const { onChange } = this.props;
    if (onChange) {
      onChange(changedValue);
    }
  };

  render() {
    const { mapProps, bodyStyle, ...inputProps } = this.props;
    const { visible, value, result } = this.state;
    const position = result ? result.position : null;
    const address = result ? result.address : '';
    return (
      <React.Fragment>
        <Input
          addonBefore={MapIcon}
          {...inputProps}
          readOnly
          onClick={this.handleClick}
          onChange={this.handleChange}
          value={value}
          allowClear
        />
        <Modal
          visible={visible}
          bodyStyle={bodyStyle}
          width={bodyStyle.width}
          onOk={this.handleOk}
          onCancel={this.handleCancel}
          destroyOnClose
        >
          <Map zoom={15} {...mapProps} center={position} events={this.amapEvents}>
            {position && (
              <Marker position={position}>
                <Tooltip title={address}>
                  <MarkerIcon />
                </Tooltip>
              </Marker>
            )}
            <Address onSearch={this.handleSearch} />
          </Map>
        </Modal>
      </React.Fragment>
    );
  }
}
